package cn.ty.znsz.Login;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.jfinal.kit.HashKit;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.redis.Redis;

import cn.ty.znsz.common.model.SysUser;
import cn.ty.znsz.common.model.SysUserArea;
import cn.ty.znsz.common.model.SysUserRole;

/**
 * 本 demo 仅表达最为粗浅的 jfinal 用法，更为有价值的实用的企业级用法
 * 详见 JFinal 俱乐部: https://jfinal.com/club
 * 
 * BlogService
 * 所有 sql 与业务逻辑写在 Service 中，不要放在 Model 中，更不
 * 要放在 Controller 中，养成好习惯，有利于大型项目的开发与维护
 */
public class LoginService {
	
	/**
	 * 所有的 dao 对象也放在 Service 中，并且声明为 private，避免 sql 满天飞
	 * sql 只放在业务层，或者放在外部 sql 模板，用模板引擎管理：
	 * 			https://jfinal.com/doc/5-13
	 */
	private SysUser userDao = new SysUser().dao();
	/**
	 * 登录
	 * @param loginName
	 * @param password
	 * @return
	 */
	public Ret doLogin(String loginName, String password) {
		password = password.trim();
		SysUser user=userDao.findFirst("SELECT * from sys_user a WHERE a.loginName=? LIMIT 1;",loginName);
		if(user == null) {
			return Ret.fail("用户不存在");
		}
		if(user.getStatus()==0) {
			return Ret.fail("账号已被注销");
		}
		String salt=user.getSalt();
		String hashedPass = HashKit.sha256(salt + password);
		// 未通过密码验证
		if (user.getPassword().equals(hashedPass) == false) {
			return Ret.fail("密码不正确");
		}
		//放入缓存
		user.put("loginTime", System.currentTimeMillis());
		String token=StrKit.getRandomUUID();
		user.put("token", token);
		user.put("roleIds",Db.queryStr("SELECT GROUP_CONCAT(a.roleId) ids from sys_user_role a WHERE a.userId=?;",user.getId()));
		user.put("areaId", Db.queryInt("SELECT a.areaId from sys_user_area a WHERE a.userId=?;",user.getId()));
		Map<Object, Object> data = new HashMap<Object, Object>();
		for(String key : user._getAttrNames()){
			data.put(key, user.get(key));
		}
		String myKey="znsz-web-"+user.getId();
		Redis.use("redisW").hmset(myKey, data);
		Redis.use("redisW").setex(token, 7 * 24 * 3600, myKey);
		Redis.use("redisW").expire(myKey, 7 * 24 * 3600);
		return Ret.ok("操作成功").set("token", token);
	}
	/**
	 * 判断账号是否已经被注册
	 */
	public boolean checkLoginName(String loginName) {
		loginName = loginName.toLowerCase().trim();
		return Db.queryInt("select id from sys_user where loginName = ? limit 1", loginName) != null;
	}
	/**
	 * 注册
	 * @param para
	 * @param para2
	 * @param para3
	 * @return
	 */
	public Ret doRegister(String userName, String loginName, String password) {
		// 密码加盐 hash
		String salt = HashKit.generateSaltForSha256();
		String password2 = HashKit.sha256(salt + password);
		boolean isSuccess =Db.tx(() -> {
			SysUser user = new SysUser();
			user.setLoginName(loginName);
			user.setUserName(userName);
			user.setPassword(password2);
			user.setSalt(salt);
			user.setCreateAt(new Date());
			user.setHeadImg(PropKit.get("headImg"));  // 注册时设置默认头像
			user.use("zsql").save();
			SysUserArea sua=new SysUserArea();
			sua.setUserId(user.getId());
			sua.setAreaId(1);
			sua.use("zsql").save();
			SysUserRole sur=new SysUserRole();
			sur.setUserId(user.getId());
			sur.setRoleId(2);
			sur.use("zsql").save();
			return true;
		 });
		if (isSuccess) {
			return Ret.ok("注册成功");
		} else {
			return Ret.fail("注册失败");
		}
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
}
